"""
StarRocks MCP Server 设置管理模块

集中管理所有配置，支持环境变量、.env文件和URL三种配置方式。
解决环境变量读取时机不一致的问题。
"""
import os
from typing import Optional, Dict, Any
from dataclasses import dataclass
from pathlib import Path


@dataclass
class DatabaseConfig:
    """数据库连接配置"""
    host: str = "localhost"
    port: int = 9030
    user: str = "root"
    password: str = ""
    database: Optional[str] = None
    auth_plugin: str = "mysql_native_password"
    pool_size: int = 10
    pool_name: str = "mcp_starrocks_pool"
    pool_reset_session: bool = True
    autocommit: bool = True
    connection_timeout: int = 10
    connect_timeout: int = 10


@dataclass
class ServerConfig:
    """服务器配置"""
    enable_arrow_flight_sql: bool = False
    fe_arrow_flight_sql_port: Optional[str] = None
    enable_dummy_test: bool = False
    overview_length_limit: int = 20000


class Settings:
    """设置管理类 - 单例模式"""
    
    _instance: Optional['Settings'] = None
    _initialized: bool = False
    
    def __new__(cls) -> 'Settings':
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self):
        if not self._initialized:
            self._load_env_file()
            self._load_from_environment()
            Settings._initialized = True
    
    def _load_env_file(self):
        """从 .env 文件加载环境变量"""
        # 查找 .env 文件，从当前目录开始向上查找
        current_dir = Path(__file__).parent
        project_root = current_dir.parent.parent  # 项目根目录
        
        env_files = [
            current_dir / '.env',
            project_root / '.env',
            Path.cwd() / '.env',
            Path.home() / '.env'
        ]
        
        for env_file in env_files:
            if env_file.exists():
                self._parse_env_file(env_file)
                print(f"已加载 .env 文件: {env_file}")
                break
    
    def _parse_env_file(self, env_file: Path):
        """解析 .env 文件"""
        try:
            with open(env_file, 'r', encoding='utf-8') as f:
                for line in f:
                    line = line.strip()
                    # 跳过空行和注释
                    if not line or line.startswith('#'):
                        continue
                    
                    # 解析 KEY=VALUE 格式
                    if '=' in line:
                        key, value = line.split('=', 1)
                        key = key.strip()
                        value = value.strip()
                        
                        # 移除引号
                        if value.startswith('"') and value.endswith('"'):
                            value = value[1:-1]
                        elif value.startswith("'") and value.endswith("'"):
                            value = value[1:-1]
                        
                        # 设置环境变量（如果还没有设置）
                        if key not in os.environ:
                            os.environ[key] = value
        except Exception as e:
            print(f"警告: 解析 .env 文件失败: {e}")
    
    def _load_from_environment(self):
        """从环境变量加载配置"""
        # 检查是否有 STARROCKS_URL
        url = os.getenv('STARROCKS_URL')
        if url:
            self._load_from_url(url)
        else:
            self._load_from_individual_env_vars()
        
        # 加载服务器配置
        self.server = ServerConfig(
            enable_arrow_flight_sql=bool(os.getenv('STARROCKS_FE_ARROW_FLIGHT_SQL_PORT')),
            fe_arrow_flight_sql_port=os.getenv('STARROCKS_FE_ARROW_FLIGHT_SQL_PORT'),
            enable_dummy_test=bool(os.getenv('STARROCKS_DUMMY_TEST')),
            overview_length_limit=int(os.getenv('STARROCKS_OVERVIEW_LIMIT', '20000'))
        )
    
    def _load_from_url(self, url: str):
        """从连接URL加载配置"""
        from .db_client import parse_connection_url
        
        try:
            parsed = parse_connection_url(url)
            self.database = DatabaseConfig(
                host=parsed['host'],
                port=int(parsed['port']),
                user=parsed['user'],
                password=parsed['password'],
                database=parsed.get('database'),
                auth_plugin=os.getenv('STARROCKS_MYSQL_AUTH_PLUGIN', 'mysql_native_password'),
                pool_size=int(os.getenv('STARROCKS_POOL_SIZE', '10')),
                pool_name='mcp_starrocks_pool',
                pool_reset_session=True,
                autocommit=True,
                connection_timeout=int(os.getenv('STARROCKS_CONNECTION_TIMEOUT', '10')),
                connect_timeout=int(os.getenv('STARROCKS_CONNECTION_TIMEOUT', '10'))
            )
        except Exception as e:
            print(f"警告: 解析 STARROCKS_URL 失败: {e}")
            self._load_from_individual_env_vars()
    
    def _load_from_individual_env_vars(self):
        """从单独的环境变量加载配置"""
        self.database = DatabaseConfig(
            host=os.getenv('STARROCKS_HOST', 'localhost'),
            port=int(os.getenv('STARROCKS_PORT', '30031')),
            user=os.getenv('STARROCKS_USER', 'root'),
            password=os.getenv('STARROCKS_PASSWORD', ''),
            database=os.getenv('STARROCKS_DB', ''),
            auth_plugin=os.getenv('STARROCKS_MYSQL_AUTH_PLUGIN', 'mysql_native_password'),
            pool_size=int(os.getenv('STARROCKS_POOL_SIZE', '10')),
            pool_name='mcp_starrocks_pool',
            pool_reset_session=True,
            autocommit=True,
            connection_timeout=int(os.getenv('STARROCKS_CONNECTION_TIMEOUT', '10')),
            connect_timeout=int(os.getenv('STARROCKS_CONNECTION_TIMEOUT', '10'))
        )
    
    def get_connection_params(self) -> Dict[str, Any]:
        """获取数据库连接参数"""
        return {
            'host': self.database.host,
            'port': self.database.port,
            'user': self.database.user,
            'password': self.database.password,
            'database': self.database.database,
            'auth_plugin': self.database.auth_plugin,
            'pool_size': self.database.pool_size,
            'pool_name': self.database.pool_name,
            'pool_reset_session': self.database.pool_reset_session,
            'autocommit': self.database.autocommit,
            'connection_timeout': self.database.connection_timeout,
            'connect_timeout': self.database.connect_timeout,
        }
    
    def reload(self):
        """重新加载配置（用于测试）"""
        self._load_from_environment()
    
    @classmethod
    def reset(cls):
        """重置单例实例（用于测试）"""
        cls._instance = None
        cls._initialized = False


# 全局设置实例
def get_settings() -> Settings:
    """获取全局设置实例"""
    return Settings()


def reset_settings():
    """重置设置（用于测试）"""
    Settings.reset()
